<!--这个组件用于构筑一个绝对定位区域，为了保证背景图与图标在缩放时不改变定位位置，此组件必须传递确定像素的宽高。后续缩放通过zoom或者scale实现-->
<template>
  <div class="absolute-area">
    <div class="tool-bar" v-if="!readonly">
      <q-btn dense color="primary" @click="download">下载</q-btn>
    </div>
    <template v-for="item in itemListBack">
      <div v-if="!readonly" class="move-box" :style="getStyle(item)" :data-uuid="item._id" :id="'el_' + item._id" @mousedown.capture="movePanel($event, '#el_' + item._id, '.absolute-area')">
        <div class="item-box">
          <slot name="item" :row="item"></slot>
        </div>
      </div>
      <div v-if="readonly" :style="getStyle(item)" class="move-box">
        <slot name="item" :row="item"></slot>
      </div>
    </template>
  </div>
</template>

<script setup>
import {downloadBlob, json2Blob} from "dlsjs"
import {v4 as uuid} from 'uuid'
import {onBeforeMount, ref} from "vue"
import {clone} from "ramda"

const props = defineProps({
  itemList: Array,
  readonly: Boolean
})

const itemListBack = ref([])

function initItemListBack() {
  itemListBack.value = clone(props.itemList)
  itemListBack.value.forEach(item => {
    Object.defineProperty(item, '_id', {value: uuid(), enumerable: false, configurable: true, writable: true})
  })
}

function download() {
  downloadBlob(json2Blob(itemListBack.value), 'result.json')
}

function getStyle(item) {
  let style = {}
  let p = item._position
  if(!p) return style
  if(p.top) style.top = p.top + 'px'
  if(p.left) style.left = p.left + 'px'
  return style
}

function movePanel (eventDown, selector, canvasSelector) {
  eventDown.preventDefault()
  let disX = eventDown.layerX;
  let disY = eventDown.layerY;
  document.onmousemove = (eventMove) => {
    moveOption(eventMove)
  };
  document.onmouseup = () => {
    document.onmousemove = null;
    document.onmouseup = null;
  };
  const rect = document.querySelector(canvasSelector).getBoundingClientRect()
  const moveOption = (eventMove) => {
    let left = eventMove.clientX - disX - rect.left;
    let top = eventMove.clientY - disY - rect.top;
    const currentDom = document.querySelector(selector)
    currentDom.style.top = top + 'px'
    currentDom.style.left = left + 'px'
    const currentData = itemListBack.value.find(item => item._id === currentDom.dataset.uuid)
    if(!currentData._position) currentData._position = {}
    currentData._position.top = top
    currentData._position.left = left
  }
}

onBeforeMount(() => {
  initItemListBack()
})
</script>

<style scoped>
.absolute-area {
  position: relative;
}

.move-box {
  position: absolute;
  cursor: pointer;
}

.item-box {
  position: relative;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
}

.tool-bar {
  position: absolute;
  top: 0;
  right: 0;
  transform: translate(0, -100%);
}
</style>
